/********************************************************************************
 * @file    hal_nvs.c
 * @brief   nvs 操作
 * 
 * @author  nzttj
 * @date    2025-02-13
 * @version 1.0
 * 
 * Copyright (C) 2025 nztt
 * 
 * 本软件使用 GNU 通用公共许可证 (GPL) 第 3 版授权。
 * 
 * 您可以自由使用、修改、分发本软件，但必须遵守以下条件：
 * 1. 源代码必须开放，且您修改后的代码也必须以 GPL 许可证发布。
 * 2. 发布或分发本软件时，必须附带本许可证，并提供源代码或获取源代码的方式。
 * 
 * 本软件按“原样”提供，不附带任何担保，使用风险由用户自行承担。
 * 
 ********************************************************************************/

#include "hal_nvs.h"

#include "nvs_flash.h"
#include "esp_log.h"

int hal_nvs_set_blob(const char *namespace, const char *key, const void *data, size_t len)
{
    nvs_handle_t my_handle;
    int err;

    // Open
    err = nvs_open(namespace, NVS_READWRITE, &my_handle);
    if (err != ESP_OK)
    {
        return err;
    }

    err = nvs_set_blob(my_handle, key, data, len);
    if (err != ESP_OK)
    {
        ESP_LOGE("nv", "nvs set blob failed! err: %d\r\n", err);
        goto close;
    }

    // Commit
    err = nvs_commit(my_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE("nv", "nvs commit failed! err: %d\r\n", err);
        goto close;
    }

close:
    nvs_close(my_handle);
    return err;
}

int hal_nvs_get_blob(const char *namespace, const char *key, void *data, size_t len)
{
    nvs_handle_t my_handle;
    int err;

    // Open
    err = nvs_open(namespace, NVS_READONLY, &my_handle);
    if (err != ESP_OK)
    {
        return err;
    }

    size_t required_size = 0;
    err = nvs_get_blob(my_handle, key, NULL, &required_size);
    if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND)
    {
        return err;
    }

    if (required_size != len)
    {
        ESP_LOGE("nv", "data mismatch! required size: %d, expect size: %d\r\n", required_size, len);
        err = -1;
        goto close;
    }

    err = nvs_get_blob(my_handle, key, data, &required_size);
    if (err != ESP_OK)
    {
        goto close;
    }

close:
    nvs_close(my_handle);
    return err;
}

int hal_nvs_erase_key(const char *namespace, const char *key)
{
    nvs_handle_t my_handle;
    int err;

    // Open
    err = nvs_open(namespace, NVS_READWRITE, &my_handle);
    if (err != ESP_OK)
    {
        return err;
    }

    err = nvs_erase_key(my_handle, key);
    if (err != ESP_OK)
    {
        ESP_LOGE("nv", "nvs erase key failed! err: %d\r\n", err);
        goto close;
    }

    // Commit
    err = nvs_commit(my_handle);
    if (err != ESP_OK)
    {
        ESP_LOGE("nv", "nvs commit failed! err: %d\r\n", err);
        goto close;
    }

close:
    nvs_close(my_handle);
    return err;
}
